﻿#include"GraphSurface.h"

#include <QDebug>
#include <QHBoxLayout>
#include <vtkCamera.h>
#include <vtkLightKit.h>
#include <ElaMessageBar.h>
#include <vtkRenderer.h>  
#include <vtkRenderWindow.h>  
#include <vtkRenderWindowInteractor.h>  
#include <vtkGenericOpenGLRenderWindow.h>  
#include <vtkActor.h>  
#include <vtkAxesActor.h>  
#include <vtkOutputWindow.h>
#include <vtkScalarBarActor.h>  
#include <QVTKOpenGLNativeWidget.h>
#include <vtkOrientationMarkerWidget.h>
#include <vtkWindowToImageFilter.h>
#include <vtkImageResize.h>
#include <vtkJPEGWriter.h>

namespace
{
    void saveImageFromScreen(vtkWindow* window, int width, int height, QString fileName, bool autoSize)
    {
        vtkNew<vtkWindowToImageFilter> report_windowToImageFilter;
        vtkNew<vtkImageResize> report_resize;
        vtkNew<vtkJPEGWriter> report_writer;

        report_windowToImageFilter->SetInput(window);
        report_resize->SetInputConnection(report_windowToImageFilter->GetOutputPort());
        if (autoSize)
        {
            report_windowToImageFilter->Update();
            auto dimension = report_windowToImageFilter->GetOutput()->GetDimensions();
            report_resize->SetOutputDimensions(dimension[0], dimension[1], -1);
        }
        else
        {
            report_resize->SetOutputDimensions(width, height, -1);
        }
        report_resize->Update();
        report_writer->SetFileName(fileName.toStdString().c_str());
        report_writer->SetInputConnection(report_resize->GetOutputPort());
        report_writer->Write();
    }
}

namespace pst
{
    GraphSurface::GraphSurface(QWidget* parent)
        : QWidget(parent)
        , m_qvtkWidget(new QVTKOpenGLNativeWidget(this))
        , m_render3D(vtkSmartPointer<vtkRenderer>::New())
        , m_renderWindow3D(vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New())
        , m_sufaceGenerator(new TxtTo2DSurfaceGenerator(this))
        , m_leftDownCornerAxes(vtkSmartPointer<vtkAxesActor>::New())
        , m_leftDownCornerWidget(vtkSmartPointer<vtkOrientationMarkerWidget>::New())
    {
        vtkOutputWindow::SetGlobalWarningDisplay(0);

        m_qvtkWidget->setRenderWindow(m_renderWindow3D);

        // 创建渲染器并添加到窗口  
        m_renderWindow3D->AddRenderer(m_render3D);
        m_render3D->GetActiveCamera()->SetParallelProjection(true);
        m_render3D->AutomaticLightCreationOff();
        m_render3D->SetUseDepthPeeling(1);
        m_render3D->SetBackground(1, 1, 1);

        vtkNew<vtkLightKit> lightKit;
        lightKit->AddLightsToRenderer(m_render3D);
        lightKit->SetKeyLightWarmth(0.5);
        lightKit->SetFillLightWarmth(0.5);
        lightKit->SetBackLightWarmth(0.5);
        lightKit->SetHeadLightWarmth(0.5);

        QHBoxLayout* layout = new QHBoxLayout(this);
        layout->setContentsMargins(0, 0, 0, 0);
        layout->setStretch(0, 1);
        layout->setStretch(1, 0);
        layout->addWidget(m_qvtkWidget);

        //AddCornerAxes();
    }

    GraphSurface::~GraphSurface()
    {
    }

    void GraphSurface::addSurfaceActor(const QString& fileName)
    {
        m_sufaceGenerator->setFilename(fileName);
        auto isSuc = m_sufaceGenerator->update();
        if (!isSuc)
        {
            ElaMessageBar::error(ElaMessageBarType::PositionPolicy::BottomLeft, "错误", "三维图数据读取错误", 1000, this);
            return;
        }
        auto actor = m_sufaceGenerator->getActor();
        auto scalarBarActor = m_sufaceGenerator->getScalarBar();
        m_render3D->AddActor(actor);
        m_render3D->AddActor(scalarBarActor);
        m_render3D->ResetCamera();
        m_renderWindow3D->Render();
    }

    void GraphSurface::AddCornerAxes()
    {
        m_leftDownCornerAxes->SetPosition(0, 0, 0);
        m_leftDownCornerAxes->SetTotalLength(12, 12, 12);
        m_leftDownCornerAxes->SetShaftType(0);
        m_leftDownCornerAxes->SetCylinderRadius(0.02);

        m_leftDownCornerWidget->SetOrientationMarker(m_leftDownCornerAxes);
        m_leftDownCornerWidget->SetInteractor(m_renderWindow3D->GetInteractor());
        m_leftDownCornerWidget->KeyPressActivationOff();
        m_leftDownCornerWidget->SetEnabled(1);
        m_leftDownCornerWidget->InteractiveOff();
    }

    bool GraphSurface::saveScreenShot(const QString& path)
    {
        saveImageFromScreen(m_renderWindow3D, 1920, 1080, path, true);
        return true;
    }
}
